﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using IMPression;

namespace IMPressive
{
    /// <summary>
    /// Logique d'interaction pour GraphWindow.xaml
    /// </summary>
    public partial class PolarGraphWindow : Window
    {
        private Polyline pl;

        private EquationParser parser = new EquationParser();

        public PolarGraphWindow()
        {
            InitializeComponent();
            txtOperation.ItemsSource = Funcs;
        }

        private void txtOperation_KeyUp(object sender, KeyEventArgs e)
        {
            if(e.Key == Key.Enter)
            {
                Graph();
            }
        }

        public List<string> Funcs
        {
            get
            {
                var st = new List<string>() { "theta" };
                Function.FunctionsList.All(x =>
                {
                    st.Add(x.Contains('(') ? x.Substring(0, x.IndexOf('(')) : x);
                    return true;
                });
                st = st.OrderBy(x => x).Distinct().ToList();
                return st;
            }
        }

        private double thetamin = -(Constant.Pi);
        private double thetamax = Constant.Pi;
        private double dtheta = 0.1;

        void Graph()
        {
            txtOperation.Text = parser.CleanUp(txtOperation.Text);
            try
            {
                pl = new Polyline();
                pl.Stroke = new SolidColorBrush(cpxColor.SelectedColor);
                pl.StrokeThickness = 2;

                thetamin = parser.Calculate(parser.DeCleanUp(txtFromX.Text));
                thetamax = parser.Calculate(parser.DeCleanUp(txtToX.Text));
                dtheta = parser.Calculate(parser.DeCleanUp(txtPasX.Text));



                for (double theta = thetamin; theta <= thetamax; theta += dtheta)
                {
                    double rho = 0;

                    try
                    {
                        rho = parser.Calculate(parser.DeCleanUp(txtOperation.Text), "theta=" + theta);
                    }
                    catch
                    {
                        continue;
                    }

                    double x = rho * Math.Cos(theta);
                    double y = rho * Math.Sin(theta);
                    double x0 = chartCanvas.ActualWidth / 2;
                    double y0 = chartCanvas.ActualHeight / 2;

                    double xf = x0 + (x * 30);
                    double yf = y0 - (y * 30 - 30);

                    pl.Points.Add(new Point(xf, yf));
                }

                /*for (int i = 0; i < chartCanvas.ActualWidth; i++)
                {
                    double x = i;
                    double y = 0;
                    try
                    {
                        y = 30 * parser.Calculate(parser.DeCleanUp(txtOperation.Text), "x=" + ((x - NWidth / 2) / 30));
                    }
                    catch
                    {
                        continue;
                    }
                    if (double.IsInfinity(y) || double.IsNaN(y))
                    {
                        continue;
                    }
                    pl.Points.Add(new Point(i, -y + NHeight / 2));
                }*/

                chartCanvas.Children.Add(pl);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erreur : " + ex.Message, "Erreur", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            
            

            
        }

        private int NWidth
        {
            get { return (int) (chartCanvas.ActualWidth) / 30 * 30 + 30; }
        }

        private int NHeight
        {
            get { return (int) (chartCanvas.ActualHeight) / 30 * 30 + 30; }
        }

        private void btnLoad_Click(object sender, RoutedEventArgs e)
        {
            Graph();
        }

        void loadcenter()
        {
            

            var line = new Line
            {
                Stroke = Brushes.Black,
                X1 = (int)(chartCanvas.ActualWidth / 2) / 30 * 30 + 30,
                Y1 = 0,
                X2 = (int)(chartCanvas.ActualWidth / 2) / 30 * 30 + 30,
                Y2 = chartCanvas.ActualHeight,
                StrokeThickness = 1
            };
            var line2 = new Line
            {
                Stroke = Brushes.Black,
                X1 = 0,
                Y1 = (int)(chartCanvas.ActualHeight / 2) / 30 * 30 + 30,
                X2 = chartCanvas.ActualWidth,
                Y2 = (int)(chartCanvas.ActualHeight / 2) / 30 * 30 + 30,
                StrokeThickness = 1
            };

            chartCanvas.Children.Add(line);
            
            chartCanvas.Children.Add(line2);
        }

        private void btnClear_Click(object sender, RoutedEventArgs e)
        {
            chartCanvas.Children.Clear();
            loadcenter();

        }

        double ScaleRate = 1.1;

        private void chartCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (e.Delta > 0)
            {
                st.ScaleX *= ScaleRate;
                st.ScaleY *= ScaleRate;
            }
            else
            {
                if (st.ScaleX <= 1)
                    return;

                st.ScaleX /= ScaleRate;
                st.ScaleY /= ScaleRate;
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            loadcenter();
            chartCanvas.RenderTransformOrigin = new Point(0.5,
                0.5);
        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            
        }


        private void chartCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (st.ScaleX != 1 && e.LeftButton != MouseButtonState.Pressed)
                return;

            double x = 1 / (chartCanvas.ActualWidth / Mouse.GetPosition(chartCanvas).X);
            double y = 1 / (chartCanvas.ActualHeight / Mouse.GetPosition(chartCanvas).Y);
            chartCanvas.RenderTransformOrigin = new Point(x, y);
        }

        private void txtOperation_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (osi == (txtOperation.SelectedItem == null ? "" : txtOperation.SelectedItem.ToString())) return;
            if (osi != txtOperation.Text) return;
            if (txtOperation.IsDropDownOpen) return;

            if (txtOperation.Text.Contains('('))
            {
                txtOperation.Text = txtOperation.Text.Substring(0, txtOperation.Text.IndexOf('('));
            }
        }

        private string osi = "";
        private void txtOperation_DropDownClosed(object sender, RoutedPropertyChangedEventArgs<bool> e)
        {
            if (txtOperation.SelectedItem == null) return;
            osi = txtOperation.SelectedItem.ToString();
        }


    }
}
